package com.think.cloud.thinkshop.mall.mapper;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.think.cloud.thinkshop.mall.controller.admin.product.vo.ProductPageReqVO;
import com.think.cloud.thinkshop.mall.controller.app.product.vo.AppProductPageReqVO;
import com.think.cloud.thinkshop.mall.enums.category.CategoryRelationEnum;
import com.think.cloud.thinkshop.mall.enums.product.ProductShowEnum;
import com.think.cloud.thinkshop.mall.enums.product.ProductSortEnum;
import org.apache.ibatis.annotations.Mapper;
import com.think.cloud.thinkshop.mall.domain.Product;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * 商品Mapper接口
 *
 * @author zkthink
 * @date 2024-05-09
 */
@Mapper
public interface ProductMapper extends BaseMapper<Product> {

    default List<Product> selectList(ProductPageReqVO vo) {
        return selectList(new LambdaQueryWrapper<Product>()
                .in(CollectionUtil.isNotEmpty(vo.getProductIds()), Product::getProductId, vo.getProductIds())
                .like(ObjectUtil.isNotNull(vo.getProductCode()), Product::getProductCode, vo.getProductCode())
                .like(ObjectUtil.isNotNull(vo.getProductName()), Product::getProductName, vo.getProductName())
                .eq(ObjectUtil.isNotNull(vo.getIsShow()), Product::getIsShow, vo.getIsShow())
                .eq(ObjectUtil.isNotNull(vo.getCategoryId()), Product::getCategoryId, vo.getCategoryId())
                .and(ObjectUtil.isNotNull(vo.getKey()), wq -> {
                    wq.like(Product::getProductCode, vo.getKey()).or()
                            .like(Product::getProductName, vo.getKey());
                })
                .isNull(ObjectUtil.isNotNull(vo.getIsRelation()) && CategoryRelationEnum.NO.getValue().equals(vo.getIsRelation()), Product::getCategoryId)
                .isNotNull(ObjectUtil.isNotNull(vo.getIsRelation()) && CategoryRelationEnum.YES.getValue().equals(vo.getIsRelation()), Product::getCategoryId)
                .between(ObjectUtil.isNotNull(vo.getStartTime()) && ObjectUtil.isNotNull(vo.getEndTime()),
                        Product::getCreateTime, vo.getStartTime(), vo.getEndTime())
                .orderByDesc(Product::getProductId));
    }

    default List<Product> selectList(AppProductPageReqVO vo) {
        LambdaQueryWrapper<Product> qw = new LambdaQueryWrapper<Product>()
                .like(ObjectUtil.isNotNull(vo.getProductName()), Product::getProductName, vo.getProductName())
                .in(CollectionUtil.isNotEmpty(vo.getCategoryIds()), Product::getCategoryId, vo.getCategoryIds())
                .in(CollectionUtil.isNotEmpty(vo.getProductIds()), Product::getProductId, vo.getProductIds())
                .eq(vo.getProductIds() != null && vo.getProductIds().isEmpty(), Product::getProductId, -1)
                .notIn(CollectionUtil.isNotEmpty(vo.getExcludeProductIds()), Product::getProductId, vo.getExcludeProductIds())
                .eq(Product::getIsShow, ProductShowEnum.YES.getValue());
        switch (ProductSortEnum.toEnum(vo.getSort())) {
            case NEW:
                qw.orderByDesc(Product::getProductId);
                break;
            case SALES_ASC:
                qw.orderByAsc(Product::getSales);
                break;
            case SALES_DESC:
                qw.orderByDesc(Product::getSales);
                break;
            case PRICE_ASC:
                qw.orderByAsc(Product::getMinPrice);
                break;
            case PRICE_DESC:
                qw.orderByDesc(Product::getMinPrice);
                break;
            default:
                // 推荐权重分配为商品浏览量占比70%+订单成交数量占比30%
                qw.last("order by sales * 0.3 + page_views * 0.7 desc");

        }
        return selectList(qw);
    }

    @Select("<script>" +
            "SELECT mp.product_id FROM mall_product as mp " +
            "inner join mall_product_attr_value as mpav on mp.product_id = mpav.product_id " +
            "WHERE mp.deleted = 0 and ${filterSql} " +
            "group by mp.product_id" +
            "</script>")
    List<Long> intelligentSearch(@Param("filterSql") String filterSql);

    List<Product> selectListWithDeleted(@Param("productIds") List<Long> productIds);

    @Update("update mall_product set stock = stock + #{num},sales  = sales - #{num} where product_id = #{productId}")
    void addStack(@Param("productId") Long productId, @Param("num") Integer num);

    @Update("update mall_product set stock = stock - #{num},sales  = sales + #{num} where product_id = #{productId}")
    void subStack(@Param("productId") Long productId,@Param("num")  Integer num);

    @Update("update mall_product set page_views = page_views + 1 where product_id = #{productId}")
    void addPageViews(@Param("productId") Long productId);

    @Select("select * from mall_product where product_id=#{productId}")
    Product findHistoryProductById(Long productId);
}
